package com.eian.boot.common.id.config;

import com.eian.boot.common.id.formatter.IdFormatter;
import com.eian.boot.common.id.generator.SnowflakeGenerator;
import com.eian.boot.common.id.generator.UuidGenerator;
import com.eian.boot.common.id.generator.segment.DbSegmentGenerator;
import com.eian.boot.common.id.generator.segment.RedisSegmentGenerator;
import com.eian.boot.common.id.generator.sequence.DbSequenceGenerator;
import com.eian.boot.common.id.generator.sequence.RedisSequenceGenerator;
import com.eian.boot.common.id.mapper.IdFormatConfigMapper;
import com.eian.boot.common.id.mapper.IdSegmentMapper;
import com.eian.boot.common.id.obfuscator.IdObfuscator;
import com.eian.boot.common.id.service.BatchIdService;
import com.eian.boot.common.id.service.IdFormatService;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

/**
 * ID生成器自动配置类
 *
 * @author alex.meng
 */
@Slf4j
@AutoConfiguration
@EnableConfigurationProperties(IdProperties.class)
@MapperScan(basePackages = "com.eian.boot.common.id.mapper")
public class IdAutoConfiguration {

    // ==================== 基础组件（必需） ====================

    @Bean
    public UuidGenerator uuidGenerator() {
        log.debug("注册UUID生成器");
        return new UuidGenerator();
    }

    @Bean
    public SnowflakeGenerator snowflakeGenerator() {
        log.debug("注册雪花ID生成器");
        return new SnowflakeGenerator();
    }

    @Bean
    public IdFormatter idFormatter() {
        log.debug("注册ID格式化器");
        return new IdFormatter();
    }

    @Bean
    public IdObfuscator idObfuscator() {
        log.debug("注册ID混淆器");
        return new IdObfuscator();
    }

    // ==================== 格式化服务（可选） ====================

    @Bean
    public BatchIdService batchIdService(IdFormatter idFormatter, IdObfuscator idObfuscator) {
        log.debug("注册批量ID生成服务");
        return new BatchIdService(idFormatter, idObfuscator);
    }

    @Bean
    @ConditionalOnClass(name = "com.mybatisflex.core.BaseMapper")
    @ConditionalOnBean(DataSource.class)
    public IdFormatService idFormatService(
            IdFormatConfigMapper formatConfigMapper,
            IdFormatter idFormatter,
            IdObfuscator idObfuscator) {
        log.debug("注册ID格式化服务");
        return new IdFormatService(formatConfigMapper, idFormatter, idObfuscator);
    }

    // ==================== DB相关组件（可选） ====================

    @Bean
    @ConditionalOnClass(name = "com.mybatisflex.core.BaseMapper")
    @ConditionalOnBean(DataSource.class)
    public DbSegmentGenerator dbSegmentGenerator(IdSegmentMapper idSegmentMapper) {
        log.debug("注册DB号段生成器");
        return new DbSegmentGenerator(idSegmentMapper);
    }

    @Bean
    @ConditionalOnClass(name = "com.mybatisflex.core.BaseMapper")
    @ConditionalOnBean(DataSource.class)
    public DbSequenceGenerator dbSequenceGenerator(IdSegmentMapper idSegmentMapper) {
        log.debug("注册DB序列号生成器");
        return new DbSequenceGenerator(idSegmentMapper);
    }

    // ==================== Redis相关组件（可选） ====================

    @Bean
    @ConditionalOnClass(name = "org.redisson.api.RedissonClient")
    public RedisSegmentGenerator redisSegmentGenerator(
            @Autowired(required = false) RedissonClient redissonClient) {
        if (redissonClient == null) {
            log.warn("Redis号段生成器已创建，但RedissonClient未配置，使用时将抛出异常");
        } else {
            log.debug("注册Redis号段生成器");
        }
        return new RedisSegmentGenerator(redissonClient);
    }

    @Bean
    @ConditionalOnClass(name = "org.redisson.api.RedissonClient")
    public RedisSequenceGenerator redisSequenceGenerator(
            @Autowired(required = false) RedissonClient redissonClient) {
        if (redissonClient == null) {
            log.warn("Redis序列号生成器已创建，但RedissonClient未配置，使用时将抛出异常");
        } else {
            log.debug("注册Redis序列号生成器");
        }
        return new RedisSequenceGenerator(redissonClient);
    }
}

